package cn.xiuxius.embedded.comdev;

import cn.xiuxius.embedded.util.MessageUtil;
import lombok.Getter;
import lombok.Setter;
import org.jline.reader.LineReader;
import org.jline.terminal.Terminal;
import org.jline.utils.AttributedString;
import org.jline.utils.AttributedStyle;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class MessageDispatcher {


    private final Terminal terminal;

    private final LineReader lineReader;

    private final SerialPortManager portManager;


    @Getter
    @Setter
    private boolean receiveHex = false;

    @Getter
    @Setter
    private boolean sendHex = false;

    private static final DateTimeFormatter TIME_FORMATTER =
            DateTimeFormatter.ofPattern("HH:mm:ss.SSS");

    public MessageDispatcher(Terminal terminal, LineReader lineReader, SerialPortManager portManager) {
        this.terminal = terminal;
        this.lineReader = lineReader;
        this.portManager = portManager;
    }

    public void dispatchReceivedMessage(byte[] data) {
        if (!receiveHex) {
            String m = MessageUtil.bytesToString(data);
            printMessage("[Receive]", m, AttributedStyle.CYAN, true);
        } else {
            printMessage("[Receive]", MessageUtil.bytesAsString(data), AttributedStyle.CYAN, true);
        }
    }

    public void dispatchSentMessage(String message) {
        if (sendHex) {
            byte[] bytes = MessageUtil.stringAsHex(message);
            portManager.sendHex(bytes);
        } else {
            portManager.sendData(message);
        }
        printMessage("[Send]", message, AttributedStyle.GREEN, false);
    }

    public void dispatchSystemMessage(String message) {
        printMessage("[System]", message, AttributedStyle.GREEN, true);
    }

    private void printMessage(String prefix, String content, int color, boolean above) {
        String timestamp = LocalDateTime.now().format(TIME_FORMATTER);
        String output = new AttributedString(timestamp + " " + prefix + " " + content,
                AttributedStyle.DEFAULT.foreground(color)).toAnsi();
        if (!above) {
            terminal.writer().println(output);
            terminal.flush();
        } else {
            lineReader.printAbove(output);
        }
    }
}
